home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1998 September / Macworld (1998-09).dmg / Shareware World / Info / For Developers / MacZoop 1.8.3 / Required Classes / Z Sources / ZPrinter.cpp < prev    next >
Text File  |  1998-06-11  |  8KB  |  378 lines

  1. /*************************************************************************************************
  2. *
  3. *
  4. *            MacZoop - "the framework for the rest of us"         
  5. *
  6. *
  7. *
  8. *            ZPrinter.cpp            -- an object for doing printing
  9. *
  10. *
  11. *
  12. *
  13. *
  14. *            © 1996, Graham Cox
  15. *
  16. *
  17. *
  18. *
  19. *************************************************************************************************/
  20.  
  21. #include    "ZPrinter.h"
  22. #include    "ZWindow.h"
  23. #include    "MacZoop.h"
  24. #include    "ProjectSettings.h"
  25.  
  26. #if _PRINT_USING_PROGRESS_BAR
  27. #include    "ZProgress.h"
  28. #endif
  29.  
  30. /*--------------------------------***  CONSTRUCTOR  ***---------------------------------*/
  31.  
  32.  
  33. ZPrinter::ZPrinter( ZWindow* aWindow )
  34. {
  35.     printWindow = aWindow;
  36.     fakeWindow = NULL;
  37.     printInited = FALSE;
  38.     SetRect( &paperRect, 0, 0, 0, 0 );
  39.     
  40.     // create a handle for the print record. This will be initialised to
  41.     // the default print settings when the user first chooses Page Setup or Print.
  42.     
  43.     FailNIL( macPrintH = (THPrint) NewHandleClear( sizeof( TPrint )));
  44.     
  45.     // set default print record and paper size
  46.     
  47.     SetDefault();
  48.     paperRect = (*macPrintH)->prInfo.rPage;    
  49. }
  50.  
  51. /*---------------------------------***  DESTRUCTOR  ***---------------------------------*/
  52.  
  53. ZPrinter::~ZPrinter()
  54. {
  55.     if ( macPrintH )
  56.         DisposeHandle((Handle) macPrintH );
  57. }
  58.  
  59.  
  60. /*-----------------------------------***  PRINT  ***------------------------------------*/
  61. /*    
  62. print the contents of the current window
  63. ----------------------------------------------------------------------------------------*/
  64.  
  65. void    ZPrinter::Print()
  66. {
  67.     // verify that the window is valid and printable
  68.     
  69.     FailOSErr((printWindow == NULL)? kBadWindowPrintRefErr : noErr );
  70.     FailOSErr( printWindow->IsPrintable()? noErr : kBadWindowPrintRefErr );
  71.     
  72.     try
  73.     {
  74.         SetUpDocTitle( printWindow );
  75.             
  76.         PrOpen();
  77.         FailOSErr( PrError());
  78.  
  79.         PrintLoop();
  80.         PrClose();
  81.         
  82.         if ( fakeWindow )
  83.             DisposeWindow( fakeWindow );
  84.         
  85.         fakeWindow = NULL;
  86.     }
  87.     catch( OSErr err )
  88.     {
  89.         PrClose();
  90.         
  91.         if ( fakeWindow )
  92.             DisposeWindow( fakeWindow );
  93.         
  94.         fakeWindow = NULL;
  95.  
  96.         throw err;
  97.     }
  98. }
  99.  
  100. /*-----------------------------------***  PRINT  ***------------------------------------*/
  101. /*    
  102. print the contents of the window passed
  103. ----------------------------------------------------------------------------------------*/
  104.  
  105. void    ZPrinter::Print( ZWindow* aWindow )
  106. {
  107.     printWindow = aWindow;
  108.     Print();
  109. }
  110.  
  111.  
  112. /*-------------------------------***  GETPAPERRECT  ***---------------------------------*/
  113. /*    
  114. returns the paper rectangle. If not set up, this will be empty.
  115. ----------------------------------------------------------------------------------------*/
  116.  
  117. void    ZPrinter::GetPaperRect( Rect* aRect )
  118. {
  119.     *aRect= paperRect;
  120. }
  121.  
  122.  
  123. /*-----------------------------***  SETMACPRINTRECORD  ***------------------------------*/
  124. /*    
  125. allows existing print record to be set for the printer
  126. ----------------------------------------------------------------------------------------*/
  127.  
  128. void    ZPrinter::SetMacPrintRecord( THPrint pRec )
  129. {
  130.     if ( pRec == NULL )
  131.         PrintDefault( macPrintH );
  132.     else
  133.     {
  134.         if ( macPrintH )
  135.             DisposeHandle((Handle) macPrintH );
  136.             
  137.         macPrintH = pRec;
  138.         printInited = TRUE;
  139.         
  140.         paperRect = (*macPrintH)->prInfo.rPage;    
  141.     }
  142. }
  143.  
  144.  
  145. /*---------------------------------***  PAGESETUP  ***----------------------------------*/
  146. /*    
  147. display the page setup dialog
  148. ----------------------------------------------------------------------------------------*/
  149.  
  150. void    ZPrinter::PageSetUp()
  151. {
  152.     // display the page setup dialog
  153.     
  154.     try
  155.     {
  156.         PrOpen();
  157.         FailOSErr( PrError());
  158.     
  159.         SetDefault();
  160.                 
  161.         StopCursorAnimation();
  162.         PrStlDialog( macPrintH );
  163.         PrClose();
  164.         
  165.         paperRect = (*macPrintH)->prInfo.rPage;
  166.     }
  167.     catch( OSErr err )
  168.     {
  169.         PrClose();
  170.         // show the print problem alert, but do not propagate
  171.         
  172.         Str15    errStr;
  173.         NumToString( err, errStr );
  174.         ParamText( errStr, NULL, NULL, NULL );
  175.  
  176.         if (err != userCanceledErr)
  177.             (void) NotifyAlert( kInitPrinterAlertID );
  178.     }
  179. }
  180.  
  181.  
  182. /*---------------------------------***  PRINTLOOP ***-----------------------------------*/
  183. /*    
  184. display the job dialog and print the range of pages selected
  185. ----------------------------------------------------------------------------------------*/
  186.  
  187. void    ZPrinter::PrintLoop()
  188. {
  189.     Boolean        pgOpen = FALSE;
  190.     short        copies;
  191.     
  192.     // stick up the job dialog so the user can set copies, start, end, etc.
  193.     
  194.     StopCursorAnimation();
  195.     
  196.     if ( PrJobDialog( macPrintH ))
  197.     {
  198.         // user OK'd the dialog, so set the page ranges and start printing them.
  199.         // set up the paper rect. Note we set the static watch cursor since the print
  200.         // driver may do its own animation. We also do a quick window update here because
  201.         // the print dialog just went away leaving an update area, but no events are handled
  202.         // until the print job is complete.
  203.         
  204.         printWindow->PerformUpdate();
  205.         SetCursorShape( watchCursor );
  206.         
  207.         // OK, now do the real thing...
  208.         
  209.         paperRect = (*macPrintH)->prInfo.rPage;
  210.         
  211.         // calculate pagination. The window does this based on its content area and
  212.         // the paper area passed to it. Default pagination tiles first horizontally
  213.         // then vertically. pH and pV will be at least 1.
  214.         
  215.         printWindow->CalcPages( paperRect, &pH, &pV );
  216.     
  217.         pageStart = (*macPrintH)->prJob.iFstPage;
  218.         pageEnd = (*macPrintH)->prJob.iLstPage;
  219.     
  220.         // make sure the end page is sensible to the actual number of pages
  221.         // to print.
  222.         
  223.         if (pageEnd > (pH * pV))
  224.             pageEnd = (pH * pV);
  225.             
  226.         if (pageStart < 1)
  227.             pageStart = 1;
  228.             
  229.         // make the magic fix for mac happiness:
  230.             
  231.         (*macPrintH)->prJob.iFstPage = 1;
  232.         (*macPrintH)->prJob.iLstPage = 9999;
  233.         
  234.         // if using a progress bar, set it up:
  235.     
  236.     
  237.         #if _PRINT_USING_PROGRESS_BAR
  238.         
  239.         short    saveResFile = CurResFile();
  240.         
  241.         UseResFile( gApplication->GetAppRefnum());
  242.         long    max = pageEnd * (*macPrintH)->prJob.iCopies;
  243.         long    pg = 1;
  244.         Str15    pgNum, totPg;
  245.         Str255    ppTitle;
  246.         
  247.         ZProgress    ppb( gApplication, kStdProgressResID, max, kNoButton );
  248.         
  249.         NumToString( max, totPg );
  250.         
  251.         GetWTitle( fakeWindow, ppTitle );
  252.         ppb.SetTitle( ppTitle );
  253.         ppb.SetMessage( 128, 12 );
  254.         
  255.         UseResFile( saveResFile );
  256.     
  257.         #endif
  258.  
  259.  
  260.         // print the requested number of copies
  261.                 
  262.         for( copies = 0; copies < (*macPrintH)->prJob.iCopies; copies++ )
  263.         {
  264.             // if page start is later than page end, nothing to print (sanity check)
  265.         
  266.             if ( pageStart <= pageEnd )
  267.             {
  268.                 printPort = PrOpenDoc( macPrintH, NULL, NULL );
  269.                 FailOSErr( PrError());
  270.                 
  271.                 try
  272.                 {
  273.                     printWindow->PrintingStarting();
  274.                     
  275.                     // for each page, open the page and print it
  276.  
  277.                     for ( pageNum = pageStart; pageNum <= pageEnd; pageNum++ )
  278.                     {
  279.                         // if a progress bar, drive it
  280.                         
  281.                         #if _PRINT_USING_PROGRESS_BAR
  282.                         
  283.                         NumToString( pg, pgNum );
  284.                         ParamText( pgNum, totPg, NULL, NULL );
  285.                         
  286.                         if ( ! ppb.InformProgress( pg++ ))
  287.                             FailOSErr( userCanceledErr );
  288.                         
  289.                         #endif
  290.                         
  291.                         PrOpenPage( printPort, NULL );
  292.                         FailOSErr( PrError());
  293.                         
  294.                         pgOpen = TRUE;
  295.                         
  296.                         // call the window to do the relevant rendering, etc.
  297.                         
  298.                         printWindow->PrintOnePage( pageNum, paperRect );
  299.                 
  300.                         PrClosePage( printPort );
  301.                         FailOSErr( PrError());
  302.                         
  303.                         pgOpen = FALSE;
  304.                     }
  305.                     
  306.                     // the printing has finished, so inform the window
  307.                     
  308.                     printWindow->PrintingFinishing();
  309.                 }
  310.                 catch( OSErr err )
  311.                 {
  312.                     if ( pgOpen )
  313.                         PrClosePage( printPort );
  314.                         
  315.                     PrCloseDoc( printPort );
  316.                     
  317.                     throw err;
  318.                 }
  319.                 
  320.                 PrCloseDoc( printPort );
  321.                 
  322.                 FailOSErr( PrError());
  323.                 
  324.                 // we may need to spool the file, so check the spool flag
  325.                 
  326.                 TPrStatus  prStatus;
  327.                 
  328.                 if ((*macPrintH)->prJob.bJDocLoop == bSpoolLoop )
  329.                 {
  330.                     PrPicFile( macPrintH, NULL, NULL, NULL, &prStatus);
  331.                     FailOSErr( PrError());
  332.                 }
  333.             }
  334.         }
  335.     }
  336. }
  337.  
  338.  
  339.  
  340. void    ZPrinter::SetUpDocTitle( ZWindow* aWindow )
  341. {
  342.     // mac print driver assums top window is the one we are printing. This is not true if we
  343.     // have floaters, so to make sure, we create a temporary front window hidden behind the
  344.     // menubar and make sure its title is set to the doc we are printing.
  345.     
  346.     Rect    r = { 0, 0, 3, 3 };
  347.     Str31    title;
  348.     
  349.     aWindow->GetName( title );
  350.     fakeWindow = NewWindow( NULL, &r, title, TRUE, 0, (WindowPtr) -1L, FALSE, 0);
  351.     SelectWindow( fakeWindow );
  352. }
  353.  
  354.  
  355. void    ZPrinter::SetDefault()
  356. {
  357.     if ( ! printInited )
  358.     {
  359.         PrOpen();
  360.         FailOSErr( PrError());
  361.         
  362.         try
  363.         {
  364.             PrintDefault( macPrintH );
  365.             FailOSErr( PrError());
  366.             
  367.             PrClose();
  368.             
  369.             printInited = TRUE;
  370.         }
  371.         catch( OSErr err )
  372.         {
  373.             PrClose();
  374.             throw err;
  375.         }
  376.     }
  377. }
  378.